Release 10.1A: OpenEdge Development:
ProDataSets


Sample procedure: adding REPOSITION and SYNCHRONIZE

In Chapter 1, "Introducing the Progress DataSet," you learned about the REPOSITION mode for a Data-Relation. You can include this in a DATASET definition as a keyword at the end of the relation definition, or you can set it at run time as an attribute (true or false) on the relation.

When you fill a ProDataSet, REPOSITION mode on a relation causes Progress to treat the relation as deactivated and to populate the child table with all records from its Data-Source buffer, or with all those you specify in your own Data-Source query.

When you are navigating, REPOSITION mode causes Progress to reposition its default query on the relation to the correct record rather than reopening the query to select only that record.

In this section, you will extend the dsOrderWin.w example to show the effect of the REPOSITION mode on a relation. You’ll also use the SYNCHRONIZE method to readjust the queries the browses for OrderLines and Items use.

First, open dsOrder.i and add the keyword REPOSITION at the end of the LineItem relation definition, as shown:

DEFINE DATASET dsOrder FOR ttOrder, ttOline, ttItem 
    DATA-RELATION OrderLine FOR ttOrder, ttOline 
      RELATION-FIELDS (OrderNum, OrderNum) 
    DATA-RELATION LineItem FOR ttOline, ttItem 
      RELATION-FIELDS (ItemNum, ItemNum) REPOSITION. 

Next, get the window procedure to use the relation queries rather than the static queries the AppBuilder generates. When you created dsOrderWin.w, you created two static browses to show the contents of ttOline and ttItem. The AppBuilder generated queries for the temp-tables for you when you did this, and associated them with preprocessor values, as shown:

&Scoped-define OPEN-QUERY-ItemBrowse OPEN QUERY ItemBrowse FOR EACH ttItem 
    NO-LOCK INDEXED-REPOSITION. 
&Scoped-define OPEN-QUERY-OlineBrowse OPEN QUERY OlineBrowse FOR EACH ttOline 
    NO-LOCK INDEXED-REPOSITION.  
&Scoped-define OPEN-BROWSERS-IN-QUERY-dsFrame ~ 
    ~{&OPEN-QUERY-ItemBrowse}~ 
    ~{&OPEN-QUERY-OlineBrowse} 

You then used the OPEN-BROWSERS preprocessor in the LEAVE trigger for the Order Number field:

 {&OPEN-BROWSERS-IN-QUERY-{&FRAME-NAME}} 

However, now you want to use the dynamic queries the ProDataSet provides for you so that you don’t have to bother using those the AppBuilder defines.

In the Main Block of dsOrderWin.w, add these lines to associate the two browse objects with the ProDataSet relation queries:

MAIN-BLOCK: 
DO ON ERROR   UNDO MAIN-BLOCK, LEAVE MAIN-BLOCK 
   ON END-KEY UNDO MAIN-BLOCK, LEAVE MAIN-BLOCK: 
  RUN enable_UI. 
  /* Replace the default AppBuilder-generated static queries with 
     the ones that are part of the Data-Relations. */ 
  OlineBrowse:QUERY = 
      DATASET dsOrder:GET-RELATION("OrderLine"):QUERY. 
  ItemBrowse:QUERY = 
      DATASET dsOrder:GET-RELATION("LineItem"):QUERY. 
  ItemBrowse:SET-REPOSITIONED-ROW(4, "CONDITIONAL"). 
  IF NOT THIS-PROCEDURE:PERSISTENT THEN 
    WAIT-FOR CLOSE OF THIS-PROCEDURE. 
END. 

The OrderLine relation query is filtered automatically for ttOlines of the currently selected ttOrder. In the case of this sample window, there is only one ttOrder in the ProDataSet at a time. As you have seen from other examples, if there is more than one parent, the relation query filters for the current parent.

Because of the REPOSITION qualifier on the relation, the LineItem relation query doesn’t select just the ttItem for the current ttOrder. Instead, this qualifier tells Progress to leave the ttItem query open for all ttItem records, and to reposition it to the correct ttItem for the current ttOline.

The SET-REPOSITIONED-ROW method tells Progress to make the selected row the fourth row in the viewport, so it’s in the middle, unless it’s already being displayed (that’s the CONDITIONAL part).

In the LEAVE trigger for iOrderNum, you need to add statements that close the relation queries that the ttOline and ttItem browses are now using. If you don’t do this, you might see anomalous behavior when they are reopened for the ProDataSet on another Order, as shown:

IF iOrderNum NE 0 THEN 
  DO: 
      DATASET dsOrder:GET-RELATION(1):QUERY:QUERY-CLOSE(). 
      DATASET dsOrder:GET-RELATION(2):QUERY:QUERY-CLOSE().  

Remove or comment out the OPEN-BROWSERS… preprocessor. In addition, add a line to run the SYNCHRONIZE method on the top-level buffer, for ttOrder, as shown:

DO WITH FRAME dsFrame: 
   ASSIGN iCustNum:SCREEN-VALUE  = STRING(ttOrder.CustNum) 
          cCustName:SCREEN-VALUE = ttOrder.CustName 
          cRepName:SCREEN-VALUE  = ttOrder.RepName 
          dOrderTotal:SCREEN-VALUE = STRING(ttOrder.OrderTotal). 
          /* {&OPEN-BROWSERS-IN-QUERY-{&FRAME-NAME}}   */ 
          DATASET dsOrder:GET-BUFFER-HANDLE(1):SYNCHRONIZE(). 
END. 

Since you’ve connected the two browses to the relation queries, you don’t need to use the static ones anymore. But because there’s no browse at the top level, for the ttOrder fields, you need to nudge Progress and tell it to go through the steps to reopen or reposition the related queries for the current ttOrder record. This is what SYNCHRONIZE does.

When you rerun the window procedure, you can see the effect of the REPOSITION relation:

You can scroll up and down in the ItemBrowse to see that Progress has retrieved all Items into the temp-table. That’s what REPOSITION does at FILL time. As you can see, the relation query the browse is using is automatically positioned to the correct ttItem each time you select a ttOline record. That’s the part that REPOSITION does when you’re navigating a filled ProDataSet. If you want one behavior without the other, you can turn the REPOSITION attribute on and off at run time.

Just to reinforce what is happening here, try removing the REPOSITION keyword from dsOrder.i again and rerunning the window:

At fill time, Progress is loading only Items that are in one or more of your OrderLines into ttItem. When you view the data, it’s filtering ttItem to show only the one ttItem for the current ttOline in the browse. So there’s really nothing to browse in this case.


Copyright © 2005 Progress Software Corporation
www.progress.com
Voice: (781) 280-4000
Fax: (781) 280-4095